package cc.uts.edu.au;

public class CardCheck {
	  
	  /**
	   * Valid a Credit Card 
	   */
	  public static boolean validateCreditCard(String cardNumber,String cardType)
	  {
		boolean isValid=false;
		CreditCardType realCardType=getRealCardType(cardNumber);
	    if (realCardType!=null){
	    	if(realCardType==getCardType(cardType)){
	    		isValid=validCCNumber(cardNumber);
	    	}
	    	
	    }
	    return isValid;
	    }
	    
	  private static CreditCardType getCardType(String cardtype){
		  CreditCardType typeID=null;
		  if("Mastercard".equals(cardtype)){
			  typeID = CreditCardType.MASTERCARD;
		  }
		  if("Visa".equals(cardtype)){
			  typeID = CreditCardType.VISA;
		  }
		  if("American Express".equals(cardtype)){
			  typeID = CreditCardType.AMERICAN_EXPRESS;
		  }
		  if("Diners Club".equals(cardtype)){
			  typeID = CreditCardType.DINERS_CLUB;
		  }
		  return typeID;
	  }
	  /**
	   * Get the Card type
	   * by the card number
	   */
	  private static CreditCardType getRealCardType(String number) {
		  CreditCardType cardType=null;
	        
	    String onePrefixDigit = number.substring(0,1);
	    String twoPrefixDigit = number.substring(0,2);
	    String threePrefixDigit = number.substring(0,3);
	    
	    if (isNumber(number)) {
	      /**
	      * VISA  prefix=4 length=13 or 16  (can be 15 too!?! maybe)
	      */
	      if (onePrefixDigit.equals("4"))  {  
	        if (number.length() == 13 || number.length() == 16) 
	        	cardType = CreditCardType.VISA;
	        }
	      /**
	      * MASTERCARD  prefix= 51 ... 55  length= 16
	      */
	      else if (twoPrefixDigit.compareTo("51")>=0 && twoPrefixDigit.compareTo("55")<=0) {
	        if (number.length() == 16) 
	        	cardType = CreditCardType.MASTERCARD;
	        }
	      /**
	      *AMERICAN_EXPRESS  prefix=34 or 37 length=15
	      */
	      else if (twoPrefixDigit.equals("34") || twoPrefixDigit.equals("37")) {
	        if (number.length() == 15) 
	        	cardType = CreditCardType.AMERICAN_EXPRESS;
	        }
	      /**
	      * DCLUB prefix=300 ... 305 or 36 or 38 length=14
	      */
	      else if (twoPrefixDigit.equals("36") || twoPrefixDigit.equals("38") || 
	        (threePrefixDigit.compareTo("300")>=0 && threePrefixDigit.compareTo("305")<=0)) {
	        if (number.length() == 14) 
	        	cardType = CreditCardType.DINERS_CLUB;
	           }
	      }           
	      return cardType;
	      
	      
	    }
	    
	  public static boolean isNumber(String n) {
	    try  {
	      double d = Double.valueOf(n).doubleValue();
	      return true;
	      }
	    catch (NumberFormatException e) {
	      e.printStackTrace();
	      return false;
	      }
	    }

	  
	  private static boolean validCCNumber(String n) {
	    try {
	      /*
	      ** known as the LUHN Formula (mod10)
	      */
	      int j = n.length();
	  
	      String [] s1 = new String[j];
	      for (int i=0; i < n.length(); i++) s1[i] = "" + n.charAt(i);
	  
	      int checksum = 0;         
	    
	      for (int i=s1.length-1; i >= 0; i-= 2) {
	        int k = 0;
	        
	        if (i > 0) {
	           k = Integer.valueOf(s1[i-1]).intValue() * 2;
	           if (k > 9) {
	              String s = "" + k;
	              k = Integer.valueOf(s.substring(0,1)).intValue() + 
	                  Integer.valueOf(s.substring(1)).intValue();
	              }
	              checksum += Integer.valueOf(s1[i]).intValue() + k;            
	           }
	           else
	              checksum += Integer.valueOf(s1[0]).intValue();            
	        }
	      return ((checksum % 10) == 0);
	      }
	    catch (Exception e) {
	      e.printStackTrace();
	      return false;
	      }
	    }
	  
	  public static String processCardNumber(String cardNumber){
		  int cardLength=cardNumber.length();
		  String finalString="";
		  String curString=cardNumber.substring(cardLength-4);
		  for (int i = 0; i < cardLength-4; i++) {
			finalString+="*";
		}
		  
		  return finalString+curString;
	  }
}
